#include "../Interfaces/VotanteABM.h"
#include <limits>

using namespace ABM;

//Cuando llamo al constructor de IAbm , le seteo el nombre del ABM en el que estoy.
VotanteABM::VotanteABM():IAbm("Votante") {
	this->manejadorVotante = new ManejadorVotante();
	this->manejadorDistrito = new ManejadorDistrito();
}

bool VotanteABM::alta() {

	string nombreYApellido = "";
	string domicilio = "";
	string distritoVotante = "";
	string dni = "";
	string contrasenia = "";

	cout << "ALTA VOTANTE " << endl;
	cout << endl;

	cout << "Ingrese el DNI: ";
	getline(cin,dni);

	cout << "Ingrese el NOMBRE y APELLIDO: ";
	getline(cin, nombreYApellido);
	nombreYApellido = Utils::aMinuscula(nombreYApellido);

	cout << "Ingrese DOMICILIO: ";
	getline(cin, domicilio);
	domicilio = Utils::aMinuscula(domicilio);

	cout << "Ingrese el DISTRITO: ";
	getline(cin, distritoVotante);
	distritoVotante = Utils::aMinuscula(distritoVotante);

	if (!this->manejadorDistrito->existe(distritoVotante)) {
		cout << "Distrito invalido. Presione enter ..." << endl;
		getchar();
		return false;
	}
	cout << "Ingrese la CLAVE: ";
	getline(cin,contrasenia);
	cout << endl;

	return altaInterna(dni, nombreYApellido, domicilio, distritoVotante, contrasenia);
}

bool VotanteABM::altaInterna(string dni, string nombreYApellido, string domicilio, string distritoVotante, string contrasenia) {
	bool resultado;
	Votante* votante = new Votante();

	votante->setDNI(atoi(dni.c_str()));
	votante->setNombreYApellido(nombreYApellido);
	votante->setDomicilio(domicilio);
	votante->setDistrito(distritoVotante);
	votante->setClave(atoi(contrasenia.c_str()));

	resultado = manejadorVotante->alta(votante);

	delete votante;
	return resultado;
}

bool VotanteABM::baja() {

	bool resultado = false;
	string nombreYApellido = "";
	string domicilio = "";
	string distritoVotante = "";
	string dni = "";
	string contrasenia = "";

	cout << "BAJA VOTANTE " << endl;
	cout << endl;
	cout << "Ingrese el DNI: ";
	getline(cin,dni);
	cin.ignore(numeric_limits<streamsize>::max(), '\n');
	Votante* votante = this->manejadorVotante->recuperar(dni);
	if (votante != NULL) {
		resultado = manejadorVotante->baja(votante);
		delete votante;
	} else
		resultado = false;

	return resultado;

}

bool VotanteABM::modificacion() {
	bool resultado = false;
	string nombreYApellido = "";
	string domicilio = "";
	string distritoVotante = "";
	string dni = "";
	string contrasenia = "";

	cout << "MODIFICACION VOTANTES " << endl;
	cout << endl;
	cout << "Ingrese el DNI: ";
	getline(cin,dni);
	cin.ignore(numeric_limits<streamsize>::max(), '\n');

	Votante* votanteGuardado = manejadorVotante->recuperar(dni);

	if (votanteGuardado != NULL) {
		Votante* votanteModificado = this->menuModificacion(votanteGuardado);
		if (votanteModificado != NULL) {
			resultado = manejadorVotante->modificacion(votanteModificado);
			delete votanteModificado;
			delete votanteGuardado;
		}else
			resultado = false;
	} else
		resultado = false;

	return resultado;

}

Votante* VotanteABM::menuModificacion(Votante* votanteOriginal) {
	bool fin = false;
	unsigned int campoAModificar = 0;
	while (!fin) {
		campoAModificar = 0;
		system("clear");
		cout << "Ingrese el campo que desea modificar " << endl;
		cout << "               1- Nombre y Apellido : " << votanteOriginal->getNombreYApellido() << endl;
		cout << "               2- Domicilio         : " << votanteOriginal->getDomicilio() << endl;
		cout << "               3- Distrito          : " << votanteOriginal->getDistrito()->getNombre() << endl;
		cout << "               4- Contrasenia       : " << votanteOriginal->getClave() << endl;
		cout << "       		5- Volver" << endl;
		cin >> campoAModificar;
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		if (campoAModificar < 6 && campoAModificar > 0) {
			fin = true;
		} else {
			cout << endl << "Opcion incorrecta. Vuelvalo a intentar." << endl;
			getchar();
		}
	}
	Votante* votanteModificado = new Votante();
	votanteModificado->setDNI(votanteOriginal->getDNI());
	switch (campoAModificar) {
	case (1): {
		string nombreYApellido = "";
		cout << "Ingrese nuevo Nombre y Apellido: ";
		getline(cin,nombreYApellido);
		nombreYApellido = Utils::aMinuscula(nombreYApellido);
		votanteModificado->setNombreYApellido(nombreYApellido);
		votanteModificado->setDomicilio(votanteOriginal->getDomicilio());
		votanteModificado->setDistrito(votanteOriginal->getDistrito()->getNombre());
		votanteModificado->setClave(votanteOriginal->getClave());
		break;
	}
	case (2): {
		string domicilio = "";
		cout << "Ingrese nuevo Domicilio: ";
		getline(cin, domicilio);
		domicilio = Utils::aMinuscula(domicilio);
		votanteModificado->setDomicilio(domicilio);
		votanteModificado->setNombreYApellido(votanteOriginal->getNombreYApellido());
		votanteModificado->setDistrito(votanteOriginal->getDistrito()->getNombre());
		votanteModificado->setClave(votanteOriginal->getClave());
		break;
	}
	case (3): {
		string distrito = "";
		cout << "Ingrese el nuevo Distrito: ";
		getline(cin, distrito);
		if (manejadorDistrito->existe(distrito)) {
			distrito = Utils::aMinuscula(distrito);
			votanteModificado->setDistrito(distrito);
			votanteModificado->setNombreYApellido(votanteOriginal->getNombreYApellido());
			votanteModificado->setDomicilio(votanteOriginal->getDomicilio());
			votanteModificado->setClave(votanteOriginal->getClave());
		} else {
			cout << endl << "El distrito ingresado no existe "<<endl;
			getchar();
		}
		break;
	}
	case (4): {
		string clave = "";
		cout << "Ingrese la nueva clave: ";
		getline(cin, clave);
		votanteModificado->setClave(atoi(clave.c_str()));
		votanteModificado->setNombreYApellido(votanteOriginal->getNombreYApellido());
		votanteModificado->setDistrito(votanteOriginal->getDistrito()->getNombre());
		votanteModificado->setDomicilio(votanteOriginal->getDomicilio());
		break;
	}
	case (5): {
		delete votanteModificado;
		votanteModificado = NULL;
		break;
	}

	}
	return votanteModificado;
}

void VotanteABM::altaMasiva(){
	string dni = "";
	string nombreYApellido = "";
	string contrasenia = "";
	string domicilio = "";
	string distritoVotante = "";

	ArchivoAltasMasivas* arch = new ArchivoAltasMasivas("votanteCargaMasiva.txt");
	string linea;
	vector<string>* campos;

	linea = arch->leerLinea();
	while (!arch->finDeArchivo()) {
		campos = Parser::separarCampos(&linea, separadorCampos);
		if(campos->size() == 5){
			for (int i = 0; i < 5; ++i) {
				Parser::reemplazarCaracter(&campos->at(i), separadorPalabras, blanco);
				campos->at(i) = Utils::aMinuscula(campos->at(i));
			}
			dni = campos->at(0);
			nombreYApellido = campos->at(1);
			contrasenia = campos->at(2);
			domicilio = campos->at(3);
			distritoVotante = campos->at(4);
			altaInterna(dni, nombreYApellido, domicilio, distritoVotante, contrasenia);
		}
		linea = arch->leerLinea();
		this->log->escribir("Se genero Alta Masiva de Votante.");
	}
	delete arch;
}

VotanteABM::~VotanteABM() {
	delete this->manejadorVotante;
	delete this->manejadorDistrito;
}
